﻿using System;
using System.Linq.Expressions;
using AngleSharp.Dom;
using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using SqlSugar;
using WomanMotion.WebApi.Infrastructure.Common;
using WomanMotion.WebApi.Infrastructure.DataBaseCommon;
using WomanMotion.WebApi.Infrastructure.YitId;
using WomanMotion.WebApi.Model.Dtos.Classify;
using WomanMotion.WebApi.Model.Dtos.Role;
using WomanMotion.WebApi.Model.Dtos.Router;
using WomanMotion.WebApi.Model.Dtos.Users;
using WomanMotion.WebApi.Model.Entitys;
using WomanMotion.WebApi.Repository.IRepository;
using WomanMotion.WebApi.Repository.Repository;
using WomanMotion.WebApi.Service.IService;

namespace WomanMotion.WebApi.Service.Service
{
    public class UsersService : BaseCRUDService<Users, UserVM, UpdateUserDTO, CreatedUserDTO>, IUsersService
    {
        private readonly IUsersRepository _userRepository;
        private readonly IRoleService _roleService;
        private readonly IAuthoritysService _authoritysService;
        private readonly IControllerService _controllerService;
        private readonly IActionsService _actionsService;

        public UsersService(ILogger<UsersService> logger, IMapper mapper, IUsersRepository userRepository, IHttpContextAccessor httpContext, IRoleService roleService, IAuthoritysService authoritysService, IControllerService controllerService, IActionsService actionsService) : base(logger, mapper, userRepository, httpContext)
        {
            this._userRepository = userRepository;
            this._roleService = roleService;
            this._authoritysService = authoritysService;
            this._controllerService = controllerService;
            this._actionsService = actionsService;
        }

        /// <summary>
        /// 更新单个实体
        /// </summary>
        /// <param name="dto">更新dto</param>
        /// <returns>实体</returns>
        /// <exception cref="Exception">更新失败</exception>
        public override async Task<UserVM> UpdateAsync(UpdateUserDTO dto)
        {
            var userid = httpContext.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            //dto转换实体
            var entity = _mapper.Map<UpdateUserDTO, Users>(dto);
            //通过ID查询实体
            var entitytemp = await this._userRepository.GetByIDAsync(dto.Id);
            if (entitytemp == null)
            {
                return default(UserVM);
            }
            entity.Updatedtime = DateTime.Now;
            entity.Updatedby = long.Parse(userid);
            entity.Createdby = entitytemp.Createdby;
            entity.Createdtime = entitytemp.Createdtime;
            entity.Password = entitytemp.Password;
            var res = await this._userRepository.UpdateAsync(entity);
            if (res > 0)
            {
                var vm = _mapper.Map<Users, UserVM>(entity);
                return vm;
            }
            else
            {
                return default(UserVM);
            }
        }

        /// <summary>
        /// 更新密码
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns></returns>
        public async Task<bool> UPdatePwdAsync(UpdateUserPwdDTO dto)
        {
            //通过ID查询实体
            var entity = await this._userRepository.GetByIDAsync(dto.Id);
            if (entity == null)
            {
                return false;
            }
            entity.Password = dto.Password;
            var res = await this._userRepository.UpdateAsync(entity);
            if (res > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 多表分页查询
        /// </summary>
        /// <param name="pars">查询条件</param>
        /// <returns></returns>
        public async Task<PageViewBase<List<UserPageVM>>> GetCommonPageListAsync(QueryParameterBase pars)
        {
            var res = await this._userRepository.GetCommonPageListAsync<UserPageVM>(_userRepository.GetDB().Queryable<Users>()
                .InnerJoin<Role>((st, sc) => st.Roleid == sc.Id)
                .LeftJoin<Users>((st, sc, usercr) => st.Createdby == usercr.Id)
                .LeftJoin<Users>((st, sc, usercr, userup) => st.Updatedby == userup.Id)
                .Select((st, sc, usercr, userup) =>
            new UserPageVM()
            {
                Id = st.Id,
                Name = st.Name,
                Photo = st.Photo,
                Roleid = st.Roleid,
                RoleName = sc.Name,
                Phone = st.Phone,
                Email = st.Email,
                Createdby = st.Createdby,
                CreatedName = usercr.Name,
                Createdtime = st.Createdtime,
                Updatedby = st.Updatedby,
                UpdatedName = userup.Name,
                Updatedtime = st.Updatedtime,
                Ifdisable = st.Ifdisable
            }).MergeTable(), pars);
            return res;
        }

        /// <summary>
        /// 返回单条多表连接数据
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        public async Task<UserPageVM> GetCommonFirstAsync(long id)
        {
            var res = await this._userRepository.GetCommonFirstAsync<UserPageVM>(_userRepository.GetDB().Queryable<Users>()
                .InnerJoin<Role>((st, sc) => st.Roleid == sc.Id)
                .LeftJoin<Users>((st, sc, usercr) => st.Createdby == usercr.Id)
                .LeftJoin<Users>((st, sc, usercr, userup) => st.Updatedby == userup.Id)
                .Select((st, sc, usercr, userup) =>
            new UserPageVM()
            {
                Id = st.Id,
                Name = st.Name,
                Photo = st.Photo,
                Roleid = st.Roleid,
                RoleName = sc.Name,
                RoleCode = sc.Code,
                Phone = st.Phone,
                Email = st.Email,
                Createdby = st.Createdby,
                CreatedName = usercr.Name,
                Createdtime = st.Createdtime,
                Updatedby = st.Updatedby,
                UpdatedName = userup.Name,
                Updatedtime = st.Updatedtime,
                Ifdisable = st.Ifdisable
            }).MergeTable().Where(m => m.Id == id));
            return res;
        }

        /// <summary>
        ///返回单条多表连接数据
        /// </summary>
        /// <param name="expression">查询where条件</param>
        /// <returns></returns>
        public async Task<UserPageVM> GetCommonFirstAsync(Expression<Func<UserPageVM, bool>> expression)
        {
            var res = await this._userRepository.GetCommonFirstAsync<UserPageVM>(_userRepository.GetDB().Queryable<Users>()
                .InnerJoin<Role>((st, sc) => st.Roleid == sc.Id)
                .LeftJoin<Users>((st, sc, usercr) => st.Createdby == usercr.Id)
                .LeftJoin<Users>((st, sc, usercr, userup) => st.Updatedby == userup.Id)
                .Select((st, sc, usercr, userup) =>
            new UserPageVM()
            {
                Id = st.Id,
                Name = st.Name,
                Photo = st.Photo,
                Roleid = st.Roleid,
                RoleName = sc.Name,
                RoleCode = sc.Code,
                Phone = st.Phone,
                Email = st.Email,
                Createdby = st.Createdby,
                CreatedName = usercr.Name,
                Createdtime = st.Createdtime,
                Updatedby = st.Updatedby,
                UpdatedName = userup.Name,
                Updatedtime = st.Updatedtime,
                Ifdisable = st.Ifdisable
            }).MergeTable().Where(expression));
            return res;
        }

        /// <summary>
        /// 返回前端路由
        /// </summary>
        /// <param name="rolecode">角色代码</param>
        /// <returns></returns>
        public async Task<RouterVM> GetRoute()
        {
            //获取角色id
            var rolecode = httpContext.HttpContext.User.Claims.Where(m => m.Type == "RoleCode").First().Value;
            var rolevm = await _roleService.GetAsync(m => m.Code == rolecode);
            //获取角色的权限
            var authoritysVM = await _authoritysService.GetListAsync(m => m.Roleid == rolevm.Id);
            //获取权限里面的控制器集合
            var controllerList = authoritysVM.Select(m => m.Controllerid).Distinct().ToList();
            //获取权限里面的方法集合
            var actionsList = authoritysVM.Select(m => m.Actionsid).Distinct().ToList();
            //获取Path不为空的具有权限的控制器集合
            var controllerPaths = await _controllerService.GetListAsync(m => controllerList.Contains(m.Id) && m.Path != "");
            //获取Pth不为空的你有权限的方法集合
            var actionsPaths = await _actionsService.GetListAsync(m => actionsList.Contains(m.Id) && m.Path != "");
            var router = new List<FirstMenu>();
            //循环控制器
            foreach (var item in controllerPaths)
            {
                var firstMenu = new FirstMenu();
                var controllerPathAndMeta = item.Path.Split(',');
                firstMenu.path = controllerPathAndMeta[0];
                firstMenu.meta = new FirstMeta() { title = item.Name, rank = int.Parse(controllerPathAndMeta[1]) };
                var childrens = new List<Children>();
                //查询符合条件的下级方法
                var actions = actionsPaths.Where(m => m.Controllerid == item.Id).ToList();
                foreach (var itemaction in actions)
                {
                    var itemchildren = new Children();
                    var actionPathAndMeta = itemaction.Path.Split(',');
                    itemchildren.path = actionPathAndMeta[0];
                    itemchildren.name = actionPathAndMeta[2];
                    var childrenMeta = new ChildrenMeta() { title = actionPathAndMeta[1], showParent = true };
                    itemchildren.meta = childrenMeta;
                    childrens.Add(itemchildren);
                }
                firstMenu.children = childrens;
                router.Add(firstMenu);
            }
            var res = new RouterVM();
            res.router = router;
            return res;
        }
    }
}